package cvi.com.reader.network;

import android.util.Log;
import android.widget.Toast;

import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import com.orhanobut.hawk.Hawk;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import cvi.com.reader.ReaderApplication;
import cvi.com.reader.activity.LoginActivity;
import cvi.com.reader.bean.constant;
import cvi.com.reader.tool.NetWorkUtils;
import io.reactivex.Observable;
import io.reactivex.annotations.NonNull;
import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;

/**
 * Created by window on 2018/3/7.
 */

public class NetWorkManager {


    private NetWorkManager() {
    }

    private static NetWorkManager netWorkManager = new NetWorkManager();

    public static NetWorkManager getInstance() {
        return netWorkManager;
    }


    //Log信息拦截器，打印网络请求的body部分
    private static HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY);

    //设置网络缓存大小
 /*   private static File httpCacheDirectory = new File(ReaderApplication.getInstance().getCacheDir(), "cache");
    private static int cacheSize = 10 * 1024 * 1024;//10M
    private static Cache cache = new Cache(httpCacheDirectory, cacheSize);*/


    //读写控制拦截器
    private static final Interceptor httpCacheInterceptor = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {

            Request request = chain.request();
            if (!NetWorkUtils.isNetWorkAvailable(ReaderApplication.getInstance())) {
                request = request.newBuilder()
                        .cacheControl(CacheControl.FORCE_CACHE)//强制使用缓存
                        .build();
            }
            Response originalResponse = chain.proceed(request);
            if (NetWorkUtils.isNetWorkAvailable(ReaderApplication.getInstance())) {
                int maxAge = 60; //maxAge 设置最大失效时间为60秒，失效则不使用
                //有网的时候读接口上的@Headers里的配置，你可以在这里进行统一的设置
                return originalResponse.newBuilder()
                        .removeHeader("Pragma")// 清除头信息，因为服务器如果不支持，会返回一些干扰信息，不清除下面无法生效
                        .removeHeader("Cache-Control")//移除网络请求Cache-Control请求头，因为请求头不一定支持缓存。okhttp缓存是基于请求头的
                        .header("Cache-Control", "public, max-age=" + maxAge)//添加返回网络返回数据的请求头，支持缓存
                        .build();
            } else {
                int maxStale = 60 * 60 * 24 * 28; // 离线时缓存保存4周 maxStale 设置最大失效时间，失效则不使用
                return originalResponse.newBuilder()
                        .removeHeader("Pragma")
                        .removeHeader("Cache-Control")
                        .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                        .build();
            }
        }
    };

    //配置客户端信息
    private static OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(15, TimeUnit.SECONDS)
            .readTimeout(20, TimeUnit.SECONDS)
            .writeTimeout(20, TimeUnit.SECONDS)
            .addInterceptor(loggingInterceptor)//设置应用拦截器，可用于设置公共参数，头信息，日志拦截等
            .addNetworkInterceptor(httpCacheInterceptor)
            // .addInterceptor(new ReceivedTokenInterceptor())
            .addInterceptor(new AddTokenInterceptor())
           .addInterceptor(new ReceivedCookiesInterceptor())
            .addInterceptor(new AddCookiesInterceptor())
            // .cache(cache)
            .retryOnConnectionFailure(true)//错误重连
            .build();

    private NetWorkApi netWorkApi;
    private Object monitor = new Object();

    public NetWorkApi getNetWorkApiService() {
        if (netWorkApi == null) {
            synchronized (monitor) {
                if (netWorkApi == null) {
                    netWorkApi = new Retrofit.Builder()
                            .baseUrl("http://" + constant.URL + "/v1/")
                            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                            .client(client)
                            //好像不好同时支持解析json或者String
                            .addConverterFactory(GsonConverterFactory.create()) //支持json解析
                            .addConverterFactory(ScalarsConverterFactory.create()) //支持String解析
                            .build().create(NetWorkApi.class);
                }
            }
        }

      /*  String ipAdress = "";
        String preIpAdress = "";
        if (Hawk.contains("ip")) {
            ipAdress = Hawk.get("ip");
        }
        if (Hawk.contains("preIp")) {
            preIpAdress = Hawk.get("preIp");
        }
//APP运行起来的情况下，判断两次ip是否一样再确定是否重新创建netWorkApi
        if (ipAdress.equals(preIpAdress)) {
            if (netWorkApi == null) {
                synchronized (monitor) {
                    if (netWorkApi == null) {
                        netWorkApi = new Retrofit.Builder()
                                .baseUrl("http://" + ipAdress + "/v1/")
                                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                                .client(client)
                                //好像不好同时支持解析json或者String
                                .addConverterFactory(GsonConverterFactory.create()) //支持json解析
                                .addConverterFactory(ScalarsConverterFactory.create()) //支持String解析
                                .build().create(NetWorkApi.class);
                        Hawk.put("preIp", ipAdress);
                    }
                }
            }

        } else {
            netWorkApi = new Retrofit.Builder()
                    .baseUrl("http://" + ipAdress + "/v1/")
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(client)
                    //好像不好同时支持解析json或者String
                    .addConverterFactory(GsonConverterFactory.create()) //支持json解析
                    .addConverterFactory(ScalarsConverterFactory.create()) //支持String解析
                    .build().create(NetWorkApi.class);
            Hawk.put("preIp", ipAdress);
        }*/

        return netWorkApi;
    }
  /*  public class AddCookiesInterceptor implements Interceptor {

        @Override
        public Response intercept(@NonNull Chain chain) throws IOException {
            final Request.Builder builder = chain.request().newBuilder();
            Observable.just(SpUtil.getString(GlobalConstant.COOKIES))
                    .subscribe(new Action1<String>() {
                        @Override
                        public void call(String cookie) {
                            //添加cookie
                            builder.addHeader("cookie", cookie);
                        }
                    });
            return chain.proceed(builder.build());
        }

    }
    public class ReceivedCookiesInterceptor implements Interceptor {

        @Override
        public Response intercept(@NonNull Chain chain) throws IOException {
            Response originalResponse = chain.proceed(chain.request());
            if (!originalResponse.headers("set-cookie").isEmpty()) {
                final StringBuffer cookieBuffer = new StringBuffer();
                Observable.from(originalResponse.headers("set-cookie"))
                        .map(new Func1<String, String>() {
                            @Override
                            public String call(String s) {
                                String[] cookieArray = s.split(";");
                                return cookieArray[0];
                            }
                        })
                        .subscribe(new Action1<String>() {
                            @Override
                            public void call(String cookie) {
                                cookieBuffer.append(cookie).append(";");
                            }
                        });
                SpUtil.setString(GlobalConstant.COOKIES, cookieBuffer.toString());
            }
            return originalResponse;
        }

    }*/
}
